/**
 * User控制器模块
 * controller\user.js
 *
 */
 
const express = require("express");
 
const util = require("../common/util");
/**
 * @typedef {UserDB}
 */
const UserDB = require("../model/sqlite/user");
const config = require("../common/config");
 
	/**
 * 获取用户信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
  function find(req, res) {
    (async function () {
      let db = UserDB.getInstance();
      await db.connect();
      let result = await db.find(req.params.id);
      //await db.close();
      result.fullAvatar=config.serverUrl+"/"+result.avatar;
      result.roleName = (()=>{
        if(result.role===1){
          return "管理组";
        }else if(result.role===2){
          return "普通用户组";
        }
      })();
      util.logFormat(`获取【${req.params.id}】用户信息%O`, result);
      res.json(
        util.FormatJSONData(200, `获取用户信息【${req.params.id}】`, result)
      );
    })().catch(err=>{
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误"));
    });
  }
   
  /**
   * 获取用户信息列表
   * @param {express.Request} req  请求
   * @param {express.Response} res  响应
   */
  function findAll(req, res) {
    (async function () {
      //1.处理输入的数据
      //FIXME: 输入数据的正确性校验，一致性校验，完整性校验
      let limit = req.query.limit ? req.query.limit : -1;
      let offset = req.query.offset ? req.query.offset : -1;
      //2. 访问数据
      let db = UserDB.getInstance();
      await db.connect();
      let result = await db.findAll(limit, offset);
      //await db.close();
   
      //3.输出数据
      util.logFormat(`获取【limit=${limit}&offset=${offset}】用户信息%O`, result);
      res.json(util.FormatJSONData(200, `获取用户信息列表`, result));
    })().catch(err=>{
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误"));
    });
  }
   
  /**
   * 新增用户信息
   * @param {express.Request} req  请求
   * @param {express.Response} res  响应
   */
  function add(req, res) {
    (async function () {
      //FIXME:req.body的数据安全性校验
      let user = {
        username: req.body.username,
        password: util.md5pwd(req.body.password),
        nickname: req.body.nickname,
        truename: req.body.truename,
        avatar: req.body.avatar,
        role: req.body.role,
        lastLoginTime: 0,
        lastLoginIP: "never login",
        createdTime: Date.now(),
        createdIP: util.getReqRemoteIP(req),
        updatedTime: Date.now(),
      };
      let db = UserDB.getInstance();
      await db.connect();
      //FIXME:插入数据前，考虑校验是否已存在ISBN
      let result = await db.add(user);
      //await db.close();
      util.log(`新增用户信息：lastID->${result}`);
      res.json(util.FormatJSONData(201, `新增用户信息`, { lastID: result }));
    })().catch(err=>{
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误"));
    });
  }
   
  /**
   * 更新用户信息
   * @param {express.Request} req  请求
   * @param {express.Response} res  响应
   */
  function update(req, res) {
    (async function () {
      //FIXME:req.body的数据安全性校验
      let user = {
        id: req.params.id,
        username: req.body.username,
        password: util.md5pwd(req.body.password),
        nickname: req.body.nickname,
        truename: req.body.truename,
        avatar: req.body.avatar,
        role: req.body.role,
        updatedTime: Date.now(),
      };
   
      let db = UserDB.getInstance();
      await db.connect();
      let result = await db.update(user);
      //await db.close();
      util.log(`更新用户信息：changes->${result}`);
      res.json(util.FormatJSONData(200, `更新用户信息`, { changes: result }));
    })().catch(err=>{
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误"));
    });
  }
   
  /**
   * 删除用户信息
   * @param {express.Request} req  请求
   * @param {express.Response} res  响应
   */
  function remove(req, res) {
    (async function () {
      //FIXME:数据合法性校验
      let userId = req.params.id;
      let db = UserDB.getInstance();
      await db.connect();
      let result = await db.remove(userId);
      //await db.close();
      util.log(`删除用户信息：changes->${result}`);
      res.json(util.FormatJSONData(204, `删除用户信息`, { changes: result }));
    })().catch(err=>{
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误"));
    });
  }
   
	/**
 * 获取用户总数
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
  function getCount(req, res) {
    (async function () {
      let db = UserDB.getInstance();
      await db.connect();
      let result = await db.getCount();
      //await db.close();
      util.log(`获取用户总数：${JSON.stringify(result)}`);
      res.json(util.FormatJSONData(200, `获取用户总数息`, { result: result }));
    })().catch(err=>{
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误"));
    });
  }


  /**
 * 按关键搜索用户信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function search(req, res) {
  (async function () {
    //1.处理输入的数据
    //FIXME: 输入数据的正确性校验，一致性校验，完整性校验
    let q = req.query.q;
    let limit = req.query.limit ? req.query.limit : -1;
    let offset = req.query.offset ? req.query.offset : -1;
    //2. 访问数据
    let db = UserDB.getInstance();
    await db.connect();
    let result = await db.search(q, limit, offset);
    //await db.close();
 
    //3.输出数据
    util.logFormat(`获取关键字为【${q}】【limit=${limit}&offset=${offset}】用户信息%O`, result);
    res.json(util.FormatJSONData(200, `获取指定关键字的用户信息列表`, result));
  })().catch(err=>{
    util.err(err);
    res.json(util.FormatJSONData(500, "服务器内部错误"));
  });
}
 
  /**
   * 注册用户
   * @param {express.Request} req  请求
   * @param {express.Response} res  响应
   */
  function register(req, res) {
    (async function () {
      //FIXME:req.body的数据安全性校验
      let user = {
        username: req.body.username,
        password: util.md5pwd(req.body.password),
        nickname: req.body.nickname ? req.body.nickname : "",
        truename: req.body.truename ? req.body.truename : "",
        avatar: req.body.avatar ? req.body.avatar : "",
        role: 2,
        lastLoginTime: 0,
        lastLoginIP: "never login",
        createdTime: Date.now(),
        createdIP: util.getReqRemoteIP(req),
        updatedTime: Date.now(),
      };
      let db = UserDB.getInstance();
      await db.connect();
      let result = await db.register(user);
      //await db.close();
      util.log(`注册用户信息：lastID->${result}`);
      res.json(util.FormatJSONData(201, `注册用户`, { lastID: result }));
    })().catch(err=>{
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误", {Error: err}));
    }).catch(err=>{
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误"));
    });
  }


  /**
   * 用户登录
   * @param {express.Request} req  请求
   * @param {express.Response} res  响应
   */
  function login(req, res) {
    (async function () {
      //FIXME:req.body的数据安全性校验
      let username = req.body.username;
      let password = util.md5pwd(req.body.password);
  
      let msg = `用户【${username}】登录失败，请检查用户名和密码`;
      let data = { loginStatus: "failed" };
  
      let db = UserDB.getInstance();
      await db.connect();
      let result = await db.login(username, password);
  
      if (result) {
        msg = `用户【${username}】登录成功`;
        data = {
          loginStatus: "success",
          userId: result.id,
          username: result.username,
          nickname: result.nickname,
          truename: result.truename,
          role: result.role,
        };
        let lastLogin = {
          time: Date.now(),
          ip: util.getReqRemoteIP(req),
        };
        await db.touch(username, lastLogin);
        //使用session保存登录状态
        req.session.isLogin = true;
        req.session.user = result;
      }
      //await db.close();
      util.logFormat(`用户【${username}】登录，用户信息%O`, result);
      res.json(util.FormatJSONData(200, msg, data));
    })().catch(err=>{
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误"));
    });
  }
 
/**
 * 用户退出
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function logout(req, res) {
  util.log(`当前session内容：${JSON.stringify(req.session)}`);
  util.log(`用户退出${req.session.user}`);
  if (req.session.user) {
    let username = req.session.user.username;
    req.session.destroy((err) => util.log(err));
    util.log(`用户【${username}】退出，用户session值【${req.session}】`);
    res.json(
      util.FormatJSONData(200, `用户【${username}】退出系统`, {
        logoutStatus: "success",
      })
    );
  } else {
    res.json(util.FormatJSONData(200, `非正确访问路径`));
  }
}


/**
 * 修改个人信息
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
function changeInfo(req, res) {
  (async function () {
    //FIXME:req.body的数据安全性校验
    let info = {
      nickname: req.body.nickname,
      truename: req.body.truename,
      avatar: req.body.avatar,
    };
    let id = req.session.user.id;
 
    let db = UserDB.getInstance();
    await db.connect();
    let result = await db.changeInfo(id, info);
    //await db.close();
    util.log(`修改个人信息：changes->${result}`);
    res.json(util.FormatJSONData(200, `修改个人信息成功`, { changes: result }));
  })().catch(err=>{
    util.err(err);
    res.json(util.FormatJSONData(500, "服务器内部错误"));
  });
}

	/**
 * 修改用户密码
 * @param {express.Request} req  请求
 * @param {express.Response} res  响应
 */
  function changePassword(req, res) {
    (async function () {
      //FIXME:req.body的数据安全性校验
      let password = util.md5pwd(req.body.password);
      let id = req.session.user.id;
   
      let db = UserDB.getInstance();
      await db.connect();
      let result = await db.changePassword(id, password);
      //await db.close();
      util.log(`修改用户密码：changes->${result}`);
      res.json(util.FormatJSONData(200, `修改个人密码成功`, { changes: result }));
    })().catch(err=>{
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误"));
    });
  }
   
  /**
   * 重置用户密码
   * @param {express.Request} req  请求
   * @param {express.Response} res  响应
   */
  function resetPassword(req, res) {
    (async function () {
      //FIXME:req.body的数据安全性校验
      let password = util.md5pwd("123456");
      let id = req.params.id;
   
      let db = UserDB.getInstance();
      await db.connect();
      let result = await db.changePassword(id, password);
      //await db.close();
      util.log(`重置用户密码：changes->${result}`);
      res.json(util.FormatJSONData(200, `用户密码重置成功`, { changes: result }));
    })().catch(err=>{
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器内部错误"));
    });
  }
/**
   * 用户密码校验
   * @param {express.Request} req  请求
   * @param {express.Response} res  响应
   */
  function checkPassword(req, res) {
    (async function () {
      //FIXME:req.body的数据安全性校验
      let msg = "输入密码与原密码不同！";
      let data = { isEqual: false };
      let password = util.md5pwd(req.body.password);
      let id = req.session.user.id;
   
      let db = UserDB.getInstance();
      await db.connect();
      let result = await db.find(id);
      //await db.close();
      if (result.password === password) {
        msg = "用户密码校验正确！";
        data.isEqual = true;
      }
      util.log(
        `判断用户【${id}】请求的校验密码【${req.body.password}】，是否相同：【${data.isEqual}】`
      );
      res.json(util.FormatJSONData(200, msg, data));
    })().catch((err) => {
      util.err(err);
      res.json(util.FormatJSONData(500, "服务器发生意外情况，无法完成请求！"));
    });
  }


  module.exports = {
    find,
    findAll,
    add,
    update,
    remove,
    register,
    getCount,
    search,
    login,
    logout,
    changeInfo,
    changePassword,
    resetPassword,
    checkPassword
  };